﻿/*
 * Created by SharpDevelop.
 * User: lebeda
 * Date: 27.2.2013
 * Time: 20:24
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;

using Argotic.Common;
using Argotic.Syndication;

using System.Collections.Generic;
using System.IO;
using System.Text;

using CommandLine;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using Lucene.Net.Store;

namespace updatedb_rss
{
    class Program
    {
        public static void Main(string[] args)
        {
            
            
            var options = new CmdOptions();
            if (!CommandLineParser.Default.ParseArguments(args, options)) {
                System.Environment.Exit(0);
            }
            
            LocateCommons.waitForReleaseIndexLock();
            Lucene.Net.Store.Directory directory = LocateCommons.GetIndexDirectory();
            //            Analyzer analyzer = new KeywordAnalyzer();
            Analyzer analyzer = new StandardAnalyzer(LocateCommons.LUCENE_VERSION);
            //            Analyzer analyzer = new SimpleAnalyzer();
            IndexWriter indexWriter = new IndexWriter(directory, analyzer, LocateCommons.forceCreateIndex(), IndexWriter.MaxFieldLength.UNLIMITED);
            
            try {
                
                // start of standalone delete
                if (!String.IsNullOrEmpty(options.pathToDelete)) {
                    string pathToDelete = LocateCommons.TrimLastPathSeparator(options.pathToDelete);
                    pathToDelete = LocateCommons.LowerDriveChar(pathToDelete);
                    LocateCommons.LogToConsole("deleting path from index: "+pathToDelete);
                    
                    IndexSearcher searcher = new IndexSearcher(directory, true);
                    Query query = LocateCommons.getQueryPath(pathToDelete);
                    indexWriter.DeleteDocuments(query);
                    
                    LocateCommons.LogToConsole("deleted");
                }
                // end of standalone delete
                
                
                // start of indexing
                foreach (string url in System.IO.File.ReadAllLines(options.pathToUrl)) {
                    try {
                        url.Trim();
                        if (!url.StartsWith("#") && !String.IsNullOrWhiteSpace(url)) {
                            List<LinkItem> linkItemList = new List<LinkItem>();
                            
                            LocateCommons.LogToConsole("download chanel: "+url);
                            
                            // Download rss
                            SyndicationResourceLoadSettings settings    = new SyndicationResourceLoadSettings();
                            settings.RetrievalLimit                     = 100;
                            Uri feedUrl     = new Uri(url);
                            GenericSyndicationFeed feed    = GenericSyndicationFeed.Create(feedUrl, settings);
                            int count = 0;
                            
                            if (feed.Format == SyndicationContentFormat.Rss) {
                                RssFeed rssFeed = feed.Resource as RssFeed;
                                if (rssFeed != null)
                                {
                                    foreach (RssItem item in rssFeed.Channel.Items)
                                    {
                                        LinkItem linkItem = new LinkItem();
                                        
                                        linkItem.type = "RSS";
                                        if (item.Link != null) {
                                            linkItem.path = item.Link.AbsoluteUri;
                                        } else {
                                            linkItem.path = item.Enclosures[0].Url.AbsoluteUri;
                                        }
                                        linkItem.content = LocateCommons.prepareForContent(rssFeed.Channel.Title + "\n" + item.Title + "\n" + item.Description);
                                        linkItem.title = rssFeed.Channel.Title + " - " + item.Title;
                                        
                                        linkItemList.Add(linkItem);
                                    }
                                }
                            } else if (feed.Format == SyndicationContentFormat.Atom) {
                                AtomFeed atomFeed = feed.Resource as AtomFeed;
                                if (atomFeed != null)
                                {
                                    foreach (AtomEntry item in atomFeed.Entries)
                                    {
                                        LinkItem linkItem = new LinkItem();
                                        
                                        linkItem.type = "RSS";
                                        linkItem.path = item.Links[0].Uri.AbsoluteUri;
                                        linkItem.content = LocateCommons.prepareForContent(atomFeed.Title + "\n" + item.Title + "\n" + item.Summary.Content);
                                        linkItem.title = atomFeed.Title + " - " + item.Title;
                                        
                                        linkItemList.Add(linkItem);
                                    }
                                }
                            }
                            
                            
                            foreach(LinkItem linkItem in linkItemList)
                            {
                                try {
                                    if (!LocateCommons.keyExistsInDb(directory, linkItem.path)) {
                                        Document doc = new Document();
                                        doc.Add(new Field(LocateCommons.COL_TYPE, linkItem.type, Field.Store.YES, Field.Index.NOT_ANALYZED));
                                        doc.Add(new Field(LocateCommons.COL_CONTENT, linkItem.content, Field.Store.YES, Field.Index.ANALYZED));
                                        doc.Add(new Field(LocateCommons.COL_KEY, linkItem.path, Field.Store.YES, Field.Index.NOT_ANALYZED));
                                        doc.Add(new Field(LocateCommons.COL_TITLE, linkItem.title, Field.Store.YES, Field.Index.NOT_ANALYZED));
                                        indexWriter.AddDocument(doc);
                                        count++;
                                    }
                                } catch (Exception e) {
                                    LocateCommons.LogToConsole("Unable to write to index: " + url +": " + e.Message);
                                }
                            }
                            LocateCommons.LogToConsole("Indexed (" + feed.Format + "): " + count);
                            
                        }
                    } catch (Exception e) {
                        LocateCommons.LogToConsole("Unable to index: " + url +" ,e: " + e.Message);
                    }
                }
                
                if (options.Optimize) {
                    LocateCommons.LogToConsole("optimizing started");
                    indexWriter.Optimize();
                    LocateCommons.LogToConsole("optimized");
                } else {
                    LocateCommons.LogToConsole("optimize skiped");
                }
                
            } finally {
                
                //Close the writer
                indexWriter.Dispose();
                
                LocateCommons.LogToConsole("done");
                
            }


            // only for debug
//            Console.Write("Press any key to continue . . . ");
//            Console.ReadKey(true);
        }
    }
}